package com.flex.reflection.util;

import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ganlt
 * @since 2019/09/24 10:45
 */
public class TypeUtils {

    public static void getTypeClass(Type type, List<Class<?>> result) {
        if (type instanceof ParameterizedType) {
            Type[] types = ((ParameterizedType) type).getActualTypeArguments();
            Type retType = null;
            if (types != null && types.length > 0) {
                for (int i=0;i<types.length;i++) {
                    retType = types[i];
                    if (retType instanceof Class) {
                        result.add((Class<?>) retType);
                    } else if (retType instanceof ParameterizedType) {
                        result.add((Class<?>) ((ParameterizedType) retType).getRawType());
                    }
                }
            }
        } else if (type instanceof GenericArrayType) {
            Type genericComponentType = ((GenericArrayType) type).getGenericComponentType();
            getTypeClass(genericComponentType, result);
        } else if (type instanceof WildcardType) {
            WildcardType wildcardType = (WildcardType) type;
            Type[] lowerBounds = wildcardType.getLowerBounds();
            Type[] upperBounds = wildcardType.getUpperBounds();
            for (Type lowType : lowerBounds) {
                getTypeClass(lowType, result);
            }

            for (Type upperType : upperBounds) {
                getTypeClass(upperType, result);
            }
        } else {
            result.add((Class<?>) type);
        }

    }

    /**
     * 获取一个类型
     */
    public static Class<?> getFirstTypeClass(Type type) {
        List<Class<?>> list = new ArrayList<>();
        getTypeClass(type,list);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }
}
